package com.example.armmvvm.ui.fallview

import android.view.View
import androidx.annotation.FloatRange
import com.example.armmvvm.ui.fallview.MiddleHeightCalc.Companion.DEFAULT_MIDDLE_CALC
import com.google.android.material.bottomsheet.BottomSheetBehavior

/**
 *  author : yanghaozhang
 *  date : 2022/10/19 11:17
 *  description :
 */
class BottomFallViewSetting(
    var view: View,
    // 隐藏时回调,内部方法
    var hideCallBack: (() -> Unit)? = null,
    // 回调用于计算peekHeight和anchorHeight
    var calcHeight: ((View) -> Unit)? = null,
    // 是否可隐藏
    var hideable: Boolean = false,
    // 展示模式
    var mode: FallViewMode = FallViewMode.ONE_STATE,
    // 折叠时展示的高度
    var peekHeight: Int = 0,
    // 中间状态的位置
    var middleHeightCalc: MiddleHeightCalc = DEFAULT_MIDDLE_CALC,
    // 展开状态举例父布局顶部距离
    var expandedOffset: Int = 0,
    // 监听滑动,监听展示状态(折叠/展开/中间)的改变
    var behaviorListener: (BottomFallViewStateCallBack.() -> Unit)? = null,
    // 展示时,如果容器中为空时,是否需要初始化状态为STATE_HIDDEN,从底部弹出
    var shouldHideBottomView: Boolean = true
) : IFallViewSetting

sealed class MiddleHeightCalc {

    companion object {

        val DEFAULT_MIDDLE_CALC = RatioHeight(0.5F)

        /**
         * 设置中间状态位于父布局的百分比,值越大越靠上面
         */
        fun withRatioMiddleHeight(@FloatRange(from = 0.0, to = 1.0) halfExpandedRatio: Float): MiddleHeightCalc {
            return RatioHeight(halfExpandedRatio)
        }

        /**
         * 设置确定的距离父布局顶部的距离px
         */
        fun withDefiniteMiddleHeight(middleOffset: Int): MiddleHeightCalc {
            return DefiniteHeight(middleOffset)
        }
    }

    data class RatioHeight(@FloatRange(from = 0.0, to = 1.0) val halfExpandedRatio: Float) : MiddleHeightCalc()

    data class DefiniteHeight(val middleOffset: Int) : MiddleHeightCalc()

    fun calcBehaviorHalfExpandedRatio(parentView: View): Float {
        return when (val calc = this) {
            is DefiniteHeight -> {
                val result = 1f - (calc.middleOffset.toFloat() / parentView.height)
                result.coerceIn(0f, 1f)
            }
            is RatioHeight -> calc.halfExpandedRatio.coerceIn(0f, 1f)
        }
    }
}

class BottomFallViewStateCallBack : BottomSheetBehavior.BottomSheetCallback() {
    private var onStateChangedCallback: (OnStateChangedFunction)? = null
    private var onSlideCallback: (OnSlideFunction)? = null
    private var lastState: Int = BottomSheetBehavior.STATE_COLLAPSED
    fun onStateChanged(callback: OnStateChangedFunction) {
        onStateChangedCallback = callback
    }

    fun onSlide(callback: OnSlideFunction) {
        onSlideCallback = callback
    }

    override fun onStateChanged(bottomSheet: View, newState: Int) {
        onStateChangedCallback?.invoke(bottomSheet, lastState, newState)
        lastState = newState
    }

    override fun onSlide(bottomSheet: View, slideOffset: Float) {
        onSlideCallback?.invoke(bottomSheet, slideOffset)
    }

    internal fun reset() {
        onStateChangedCallback = null
        onSlideCallback = null
    }
}
